#include <iostream>
// 命令模式：行为型设计模式
// 可以将命令发送者和接受者完全解耦，发送者与接收者没有直接引用关系
// 实现步骤：1、提供一个抽象命令类，提供命令执行的接口
//         2、提供一个具体命令类，实现命令执行的接口
//         3、提供一个命令接收类，执行命令的对象
//         4、提供一个命令的调用类

// 命令的处理者 厨师
class Chef {
    public:
    void cook(std::string name) {
        std::cout << "厨师做一道" << name << std::endl;
    }
};

// 抽象命令类
class Command {
    public:
    Command(Chef* chef):chef_(chef) {}
    virtual void excute() = 0;

    protected:
    Chef* chef_;
};

// 具体命令类
class BeefCommand : public Command{
    public:
    BeefCommand(Chef* chef):Command(chef) {}
    void excute() override {
        this->chef_->cook("青椒牛肉");
    }
};

// 具体命令类
class PotatoCommand : public Command{
    public:
    PotatoCommand(Chef* chef):Command(chef) {}
    void excute() override {
        this->chef_->cook("青椒土豆丝");
    }
};

// 命令的接受者 服务员
class Waiter {
    public:
    void RecieveCmd(Command* cmd) {
        cmd_ = cmd;
    }
    void DealCmd() {
        cmd_->excute();
    }
    private:
    Command* cmd_;
};


int main () {
    std::cout << "hello 命令模式!!!" << std::endl;
    // 服务员
    Waiter* waiter = new Waiter();

    // 厨师
    Chef* chef = new Chef();

    // 客人点菜
    BeefCommand* beefcmd = new BeefCommand(chef);
    PotatoCommand* potatocmd = new PotatoCommand(chef);

    waiter->RecieveCmd(beefcmd);
    waiter->DealCmd();

    waiter->RecieveCmd(potatocmd);
    waiter->DealCmd();

    delete waiter;
    delete chef;
    delete beefcmd;
    delete potatocmd;

    waiter = nullptr;
    chef = nullptr;
    beefcmd = nullptr;
    potatocmd = nullptr;

    return 0;
}